#include "NetworkServer.h"
#include <algorithm>

namespace SeanNetwork {

NetworkServer::NetworkServer()
    : m_TcpAcceptor(m_IoContext),
      m_KcpSocket(m_IoContext),
      m_Running(false),
      m_NextSessionId(1),
      m_SessionCheckTimerId(0) {
}

NetworkServer::~NetworkServer() {
    Stop();
}

bool NetworkServer::Initialize(const ServerConfig& config) {
    /* 功能：初始化服务器
       参数：config-服务器配置
       返回：初始化是否成功 */
    if (m_Running) {
        return false;
    }
    
    m_Config = config;
    
    // 创建保持io_context运行的work对象
    m_Work = std::make_unique<asio::io_context::work>(m_IoContext);
    
    // 创建定时器管理器
    m_TimerManager = std::make_unique<TimerManager>(m_IoContext);
    
    return true;
}

bool NetworkServer::Start() {
    /* 功能：启动服务器
       返回：启动是否成功 */
    if (m_Running) {
        return false;
    }

	m_Running = true;

    try {
        // 启动TCP监听
        if (m_Config.TcpPort > 0) {
            if (!StartTcpListener()) {
                return false;
            }
        }
        
        // 启动KCP监听
        if (m_Config.KcpPort > 0) {
            if (!StartKcpListener()) {
                return false;
            }
        }
        
        // 启动会话超时检查定时器
        if (m_TimerManager) {
            m_SessionCheckTimerId = m_TimerManager->AddTimer(
                m_Config.SessionCheckInterval,
                [this]() {
                    CheckSessionTimeout();
                },
                TimerType::Repeated
            );
        }
        
        // 启动工作线程
        StartWorkerThreads();
        return true;
    }
    catch (const std::exception& e) {
        // 启动失败，清理资源
        Stop();
        return false;
    }
}

void NetworkServer::Stop() {
    /* 功能：停止服务器 */
    if (!m_Running) {
        return;
    }
    
    m_Running = false;
    
    // 取消定时器
    if (m_TimerManager && m_SessionCheckTimerId > 0) {
        m_TimerManager->CancelTimer(m_SessionCheckTimerId);
        m_SessionCheckTimerId = 0;
    }
    
    // 断开所有客户端连接
    {
        std::lock_guard<std::mutex> lock(m_SessionMutex);
        for (auto& pair : m_ClientSessions) {
            if (pair.second.TcpChannel) {
                pair.second.TcpChannel->Disconnect();
            }
            
            if (pair.second.KcpChannel) {
                pair.second.KcpChannel->Disconnect();
            }
        }
        
        m_ClientSessions.clear();
    }
    
    // 关闭监听套接字
    asio::error_code ec;
    m_TcpAcceptor.close(ec);
    m_KcpSocket.close(ec);
    
    // 停止工作线程
    StopWorkerThreads();
    
    // 清理定时器管理器
    if (m_TimerManager) {
        m_TimerManager->ClearAllTimers();
        m_TimerManager.reset();
    }
}

bool NetworkServer::SendMsg(ClientSessionId clientId, std::shared_ptr<NetworkMessage> message) {
    /* 功能：向指定客户端发送消息
       参数：clientId-客户端会话ID，message-要发送的消息
       返回：发送操作是否成功启动 */
    if (!message) {
        return false;
    }
    
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    auto it = m_ClientSessions.find(clientId);
    if (it == m_ClientSessions.end() || it->second.State != ConnectionState::Connected) {
        return false;
    }
    
    // 根据当前通道发送消息
    if (it->second.CurrentChannel == ChannelType::KCP && it->second.KcpChannel) {
        return it->second.KcpChannel->SendMsg(message);
    }
    else if (it->second.CurrentChannel == ChannelType::TCP && it->second.TcpChannel) {
        return it->second.TcpChannel->SendMsg(message);
    }
    
    return false;
}

void NetworkServer::BroadcastMessage(std::shared_ptr<NetworkMessage> message) {
    /* 功能：向所有客户端广播消息
       参数：message-要广播的消息 */
    if (!message) {
        return;
    }
    
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    for (auto& pair : m_ClientSessions) {
        if (pair.second.State == ConnectionState::Connected) {
            // 根据当前通道发送消息
            if (pair.second.CurrentChannel == ChannelType::KCP && pair.second.KcpChannel) {
                pair.second.KcpChannel->SendMsg(message);
            }
            else if (pair.second.CurrentChannel == ChannelType::TCP && pair.second.TcpChannel) {
                pair.second.TcpChannel->SendMsg(message);
            }
        }
    }
}

void NetworkServer::DisconnectClient(ClientSessionId clientId) {
    /* 功能：断开指定客户端连接
       参数：clientId-客户端会话ID */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    auto it = m_ClientSessions.find(clientId);
    if (it != m_ClientSessions.end()) {
        if (it->second.TcpChannel) {
            it->second.TcpChannel->Disconnect();
        }
        
        if (it->second.KcpChannel) {
            it->second.KcpChannel->Disconnect();
        }
        
        m_ClientSessions.erase(it);
    }
}

std::shared_ptr<NetworkMessage> NetworkServer::CreateMessage(uint32_t messageId, MessagePriority priority) {
    /* 功能：创建新消息
       参数：messageId-消息ID，priority-消息优先级
       返回：创建的消息对象 */
    auto message = std::make_shared<NetworkMessage>(messageId, priority);
    return message;
}

void NetworkServer::RegisterMessageHandler(uint32_t messageId, ServerMessageHandler handler) {
    /* 功能：注册消息处理回调
       参数：messageId-消息ID，handler-处理回调 */
    if (handler) {
        m_MessageHandlers[messageId] = handler;
    }
    else {
        auto it = m_MessageHandlers.find(messageId);
        if (it != m_MessageHandlers.end()) {
            m_MessageHandlers.erase(it);
        }
    }
}

void NetworkServer::SetSessionCallback(SessionStateCallback callback) {
    /* 功能：设置会话状态回调
       参数：callback-会话状态回调函数 */
    m_SessionCallback = callback;
}

size_t NetworkServer::GetConnectionCount() const {
    /* 功能：获取当前连接数
       返回：连接的客户端数量 */
    std::lock_guard<std::mutex> lock(const_cast<std::mutex&>(m_SessionMutex));
    return m_ClientSessions.size();
}

bool NetworkServer::GetClientSession(ClientSessionId clientId, ClientSession& session) const {
    /* 功能：获取客户端会话信息
       参数：clientId-客户端会话ID，session-输出的会话信息
       返回：是否找到会话 */
    std::lock_guard<std::mutex> lock(const_cast<std::mutex&>(m_SessionMutex));
    
    auto it = m_ClientSessions.find(clientId);
    if (it != m_ClientSessions.end()) {
        session = it->second;
        return true;
    }
    
    return false;
}

std::vector<ClientSessionId> NetworkServer::GetAllClientIds() const {
    /* 功能：获取所有客户端会话ID
       返回：会话ID列表 */
    std::lock_guard<std::mutex> lock(const_cast<std::mutex&>(m_SessionMutex));
    
    std::vector<ClientSessionId> result;
    result.reserve(m_ClientSessions.size());
    
    for (const auto& pair : m_ClientSessions) {
        result.push_back(pair.first);
    }
    
    return result;
}

bool NetworkServer::StartTcpListener() {
    /* 功能：启动TCP监听
       返回：启动是否成功 */
    try {
        // 关闭已有的接收器
        asio::error_code ec;
        m_TcpAcceptor.close(ec);
        
        // 创建端点
        asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), m_Config.TcpPort);
        
        // 打开接收器
        m_TcpAcceptor.open(endpoint.protocol());
        
        // 设置选项
        m_TcpAcceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
        
        // 绑定端点
        m_TcpAcceptor.bind(endpoint);
        
        // 开始监听
        m_TcpAcceptor.listen();
        
        // 开始接受连接
        AcceptTcpConnection();
        
        return true;
    }
    catch (const std::exception& e) {
        return false;
    }
}

bool NetworkServer::StartKcpListener() {
    /* 功能：启动KCP监听
       返回：启动是否成功 */
    try {
        // 关闭已有的套接字
        asio::error_code ec;
        m_KcpSocket.close(ec);
        
        // 创建端点
        asio::ip::udp::endpoint endpoint(asio::ip::udp::v4(), m_Config.KcpPort);
        
        // 打开套接字
        m_KcpSocket.open(endpoint.protocol());
        
        // 设置选项
        m_KcpSocket.set_option(asio::ip::udp::socket::reuse_address(true));
        
        // 绑定端点
        m_KcpSocket.bind(endpoint);
        
        // 开始接收数据
        ReceiveKcpData();
        
        return true;
    }
    catch (const std::exception& e) {
        return false;
    }
}

void NetworkServer::AcceptTcpConnection() {
    /* 功能：接受新的TCP连接 */
    if (!m_Running) {
        return;
    }
    
    m_TcpAcceptor.async_accept(
        [this](const asio::error_code& ec, asio::ip::tcp::socket socket) {
            HandleTcpAccept(ec, std::move(socket));
        });
}

void NetworkServer::HandleTcpAccept(const asio::error_code& ec, asio::ip::tcp::socket socket) {
    /* 功能：处理TCP连接
       参数：ec-错误码，socket-已接受的套接字 */
    if (!m_Running) {
        return;
    }
    
    if (!ec) {
        // 检查连接数限制
        size_t connectionCount = GetConnectionCount();
        if (connectionCount >= m_Config.MaxConnections) {
            // 拒绝连接
            socket.close();
        }
        else {
            // 获取客户端信息
            asio::ip::tcp::endpoint remote_ep = socket.remote_endpoint();
            asio::ip::address clientAddress = remote_ep.address();
            uint16_t clientPort = remote_ep.port();
            
            // 查找或创建会话
            ClientSessionId sessionId = FindSessionByEndpoint(clientAddress, clientPort);
            if (sessionId == 0) {
                sessionId = CreateClientSession(clientAddress, clientPort);
            }
            
            if (sessionId != 0) {
                std::lock_guard<std::mutex> lock(m_SessionMutex);
                
                auto it = m_ClientSessions.find(sessionId);
                if (it != m_ClientSessions.end()) {
                    // 创建TCP通道
                    auto tcpChannel = std::make_shared<TcpChannel>(m_IoContext);
                    if (tcpChannel->Initialize()) {
                        // 设置回调
                        tcpChannel->SetMessageCallback([this, sessionId](std::shared_ptr<NetworkMessage> message) {
                            HandleClientMessage(sessionId, message, ChannelType::TCP);
                        });
                        
                        tcpChannel->SetConnectionCallback([this, sessionId](ConnectionState state, const std::string& reason) {
                            HandleClientConnectionState(sessionId, state, reason, ChannelType::TCP);
                        });
                        
                        // 接管套接字
                        // 这里需要实现TcpChannel的接管套接字功能，略
                        
                        // 更新会话信息
                        it->second.TcpChannel = tcpChannel;
                        it->second.LastActiveTime = GetCurrentTimeMillis();
                    }
                }
            }
        }
    }
    
    // 继续接受下一个连接
    AcceptTcpConnection();
}

void NetworkServer::ReceiveKcpData() {
    /* 功能：接收KCP数据 */
    if (!m_Running) {
        return;
    }
    
    // 创建接收缓冲区
    auto receiveBuffer = std::make_shared<std::vector<uint8_t>>(2048);
    auto senderEndpoint = std::make_shared<asio::ip::udp::endpoint>();
    
    m_KcpSocket.async_receive_from(
        asio::buffer(*receiveBuffer), *senderEndpoint,
        [this, receiveBuffer, senderEndpoint](const asio::error_code& ec, std::size_t bytes_transferred) {
            HandleKcpReceive(ec, bytes_transferred, *senderEndpoint, receiveBuffer);
            ReceiveKcpData();  // 继续接收
        });
}

void NetworkServer::HandleKcpReceive(const asio::error_code& ec, std::size_t bytes_transferred,
                                  const asio::ip::udp::endpoint& sender,
                                  std::shared_ptr<std::vector<uint8_t>> receiveBuffer) {
    /* 功能：处理KCP数据接收
       参数：ec-错误码，bytes_transferred-接收到的字节数，sender-发送者端点，receiveBuffer-接收缓冲区 */
    if (!m_Running || ec) {
        return;
    }
    
    if (bytes_transferred > 0) {
        // 获取客户端信息
        asio::ip::address clientAddress = sender.address();
        uint16_t clientPort = sender.port();
        
        // 查找或创建会话
        ClientSessionId sessionId = FindSessionByEndpoint(clientAddress, clientPort);
        if (sessionId == 0) {
            sessionId = CreateClientSession(clientAddress, clientPort);
        }
        
        if (sessionId != 0) {
            std::lock_guard<std::mutex> lock(m_SessionMutex);
            
            auto it = m_ClientSessions.find(sessionId);
            if (it != m_ClientSessions.end()) {
                // 更新活动时间
                it->second.LastActiveTime = GetCurrentTimeMillis();
                
                // 处理KCP通信
                if (!it->second.KcpChannel) {
                    // 创建KCP通道
                    auto kcpChannel = std::make_shared<KcpChannel>(m_IoContext);
                    if (kcpChannel->Initialize()) {
                        // 设置KCP回调
                        kcpChannel->SetMessageCallback([this, sessionId](std::shared_ptr<NetworkMessage> message) {
                            HandleClientMessage(sessionId, message, ChannelType::KCP);
                        });
                        
                        kcpChannel->SetConnectionCallback([this, sessionId](ConnectionState state, const std::string& reason) {
                            HandleClientConnectionState(sessionId, state, reason, ChannelType::KCP);
                        });
                        
                        // 建立KCP连接
                        kcpChannel->SetupServerConnection(sender);
                        
                        // 更新会话
                        it->second.KcpChannel = kcpChannel;
                        it->second.LastActiveTime = GetCurrentTimeMillis();
                        
                        // 设置服务器端已连接状态
                        HandleClientConnectionState(sessionId, ConnectionState::Connected, "Server accepted connection", ChannelType::KCP);
                    }
                }
                
                // 处理接收到的KCP数据
                if (it->second.KcpChannel) {
                    // 将收到的数据传递给KCP通道处理
                    it->second.KcpChannel->HandleReceivedData(
                        reinterpret_cast<uint8_t*>(receiveBuffer->data()),
                        bytes_transferred,
                        sender);
                }
            }
        }
    }
}

ClientSessionId NetworkServer::CreateClientSession(const asio::ip::address& clientAddress, uint16_t clientPort) {
    /* 功能：创建新的客户端会话
       参数：clientAddress-客户端地址，clientPort-客户端端口
       返回：创建的会话ID */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    // 检查连接数限制
    size_t connectionCount = 0;
    for (const auto& pair : m_ClientSessions) {
        if (pair.second.State == ConnectionState::Connected) {
            connectionCount++;
        }
    }
    
    if (connectionCount >= m_Config.MaxConnections) {
        return 0;  // 达到最大连接数
    }
    
    // 生成新的会话ID
    ClientSessionId sessionId = GenerateSessionId();
    
    // 创建会话
    ClientSession session;
    session.Id = sessionId;
    session.Address = clientAddress;
    session.Port = clientPort;
    session.State = ConnectionState::Connecting;
    session.CurrentChannel = ChannelType::KCP;  // 默认使用KCP
    session.ConnectTime = GetCurrentTimeMillis();
    session.LastActiveTime = session.ConnectTime;
    
    // 添加到会话列表
    m_ClientSessions[sessionId] = session;
    
    // 调用会话状态回调
    if (m_SessionCallback) {
        m_SessionCallback(sessionId, ConnectionState::Connecting, "New session created");
    }
    
    return sessionId;
}

void NetworkServer::RemoveClientSession(ClientSessionId sessionId) {
    /* 功能：移除客户端会话
       参数：sessionId-会话ID */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    auto it = m_ClientSessions.find(sessionId);
    if (it != m_ClientSessions.end()) {
        // 断开连接
        if (it->second.TcpChannel) {
            it->second.TcpChannel->Disconnect();
        }
        
        if (it->second.KcpChannel) {
            it->second.KcpChannel->Disconnect();
        }
        
        // 移除会话
        m_ClientSessions.erase(it);
    }
}

void NetworkServer::HandleClientMessage(ClientSessionId clientId, std::shared_ptr<NetworkMessage> message, ChannelType channel) {
    /* 功能：处理客户端消息
       参数：clientId-客户端会话ID，message-接收到的消息，channel-消息来源通道 */
    if (!message) {
        return;
    }
    
    // 更新会话活动时间
    {
        std::lock_guard<std::mutex> lock(m_SessionMutex);
        
        auto it = m_ClientSessions.find(clientId);
        if (it != m_ClientSessions.end()) {
            it->second.LastActiveTime = GetCurrentTimeMillis();
            
            // 如果消息来自非当前通道，可以考虑进行通道评估
            if (channel != it->second.CurrentChannel) {
                // 通道质量评估逻辑，略
            }
        }
    }
    
    // 处理消息
    uint32_t messageId = message->GetHeader().MessageId;
    
    // 查找对应的消息处理器
    auto it = m_MessageHandlers.find(messageId);
    if (it != m_MessageHandlers.end() && it->second) {
        it->second(clientId, message);
    }
}

void NetworkServer::HandleClientConnectionState(ClientSessionId clientId, ConnectionState state, 
                                             const std::string& reason, ChannelType channel) {
    /* 功能：处理客户端连接状态变更
       参数：clientId-客户端会话ID，state-新状态，reason-状态变更原因，channel-状态变更的通道 */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    auto it = m_ClientSessions.find(clientId);
    if (it != m_ClientSessions.end()) {
        // 保存旧状态用于判断是否需要触发回调
        ConnectionState oldState = it->second.State;
        
        // 更新会话状态
        if (channel == it->second.CurrentChannel) {
            // 当前通道状态变更
            if (state == ConnectionState::Connected) {
                it->second.State = ConnectionState::Connected;
                it->second.LastActiveTime = GetCurrentTimeMillis();
            }
            else if (state == ConnectionState::Disconnected || state == ConnectionState::Failed) {
                // 尝试切换到备用通道
                ChannelType backupChannel = (channel == ChannelType::KCP) ? ChannelType::TCP : ChannelType::KCP;
                
                bool backupAvailable = false;
                if (backupChannel == ChannelType::KCP && it->second.KcpChannel) {
                    backupAvailable = it->second.KcpChannel->GetConnectionState() == ConnectionState::Connected;
                }
                else if (backupChannel == ChannelType::TCP && it->second.TcpChannel) {
                    backupAvailable = it->second.TcpChannel->GetConnectionState() == ConnectionState::Connected;
                }
                
                if (backupAvailable) {
                    // 切换到备用通道
                    it->second.CurrentChannel = backupChannel;
                    it->second.State = ConnectionState::Connected;
                }
                else {
                    // 没有可用的备用通道，标记为断开
                    it->second.State = state;
                }
            }
            else {
                it->second.State = state;
            }
        }
        else {
            // 备用通道状态变更
            if (state == ConnectionState::Connected && 
                (it->second.State != ConnectionState::Connected || 
                 (it->second.CurrentChannel == ChannelType::TCP && channel == ChannelType::KCP))) {
                // 如果主通道不可用，或者当前是TCP但KCP可用，则切换通道
                it->second.CurrentChannel = channel;
                it->second.State = ConnectionState::Connected;
            }
        }
        
        // 调用状态回调（只有在状态实际发生变化时才调用）
        if (m_SessionCallback && (oldState != it->second.State || state == ConnectionState::Connected)) {
            m_SessionCallback(clientId, it->second.State, reason);
        }
    }
}

void NetworkServer::CheckSessionTimeout() {
    /* 功能：检查会话超时 */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    uint64_t currentTime = GetCurrentTimeMillis();
    std::vector<ClientSessionId> timeoutSessions;
    
    for (const auto& pair : m_ClientSessions) {
        uint64_t idleTime = currentTime - pair.second.LastActiveTime;
        
        if (idleTime > m_Config.SessionTimeoutMs) {
            timeoutSessions.push_back(pair.first);
        }
    }
    
    // 移除超时会话
    for (ClientSessionId sessionId : timeoutSessions) {
        auto it = m_ClientSessions.find(sessionId);
        if (it != m_ClientSessions.end()) {
            // 调用状态回调
            if (m_SessionCallback) {
                m_SessionCallback(sessionId, ConnectionState::Disconnected, "Session timeout");
            }
            
            // 断开连接
            if (it->second.TcpChannel) {
                it->second.TcpChannel->Disconnect();
            }
            
            if (it->second.KcpChannel) {
                it->second.KcpChannel->Disconnect();
            }
            
            // 移除会话
            m_ClientSessions.erase(it);
        }
    }
}

void NetworkServer::StartWorkerThreads() {
    /* 功能：启动工作线程池
       处理：创建指定数量的工作线程运行io_context */
    StopWorkerThreads();  // 确保先停止已有线程
    
    uint32_t threadCount = m_Config.WorkerThreadCount;
    if (threadCount == 0) {
        threadCount = std::thread::hardware_concurrency();
        if (threadCount == 0) {
            threadCount = 2;  // 默认至少2个线程
        }
    }
    
    for (uint32_t i = 0; i < threadCount; ++i) {
        m_WorkerThreads.emplace_back([this]() {
            /* 线程安全保护区域：
               io_context在多线程环境下执行，通过strand保证回调的线程安全 */
            try {
                m_IoContext.run();
            }
            catch (const std::exception& e) {
                // 线程异常，可以记录日志
            }
        });
    }
}

void NetworkServer::StopWorkerThreads() {
    /* 功能：停止工作线程池 */
    if (m_Work) {
        m_Work.reset();  // 允许io_context自然退出
    }
    
    if (!m_IoContext.stopped()) {
        m_IoContext.stop();  // 强制停止所有操作
    }
    
    for (auto& thread : m_WorkerThreads) {
        if (thread.joinable()) {
            thread.join();
        }
    }
    
    m_WorkerThreads.clear();
    
    // 重置io_context供后续使用
    m_IoContext.restart();
    m_Work = std::make_unique<asio::io_context::work>(m_IoContext);
}

ClientSessionId NetworkServer::GenerateSessionId() {
    /* 功能：生成新的会话ID
       返回：唯一会话ID */
    return m_NextSessionId++;
}

ClientSessionId NetworkServer::FindSessionByEndpoint(const asio::ip::address& address, uint16_t port) {
    /* 功能：根据端点查找会话ID
       参数：address-客户端地址，port-客户端端口
       返回：找到的会话ID，未找到返回0 */
    std::lock_guard<std::mutex> lock(m_SessionMutex);
    
    for (const auto& pair : m_ClientSessions) {
        if (pair.second.Address == address && pair.second.Port == port) {
            return pair.first;
        }
    }
    
    return 0;
}

} // namespace SeanNetwork
